package com.example.common.common.config.filter;

import com.example.common.common.config.response.Response;
import com.example.common.utils.JwtUtils;
import com.example.common.utils.RedisUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;

import java.io.IOException;

/**
 * @author qwert
 * @version 1.0.0
 * @create 2025/5/2 15:14
 **/
@WebFilter("/*")
public class UserInfoFilter implements Filter {
    private static final String[] EXCLUDED_PATHS = {
            "/api/sys/auth/captcha",
            "/api/sys/auth/login",
            "/api/sys/auth/register"
    };
    private RedisUtils redisUtils;

    // 通过构造函数注入（避免 @Autowired 字段注入）
    public UserInfoFilter(RedisUtils redisUtils) {
        this.redisUtils = redisUtils;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        String requestURI = httpRequest.getRequestURI();
        for (String excludedPath : EXCLUDED_PATHS) {
            if (requestURI.equals(excludedPath)) {
                chain.doFilter(request, response);
                return;
            }
        }

        String token = httpRequest.getHeader("authorization");
        if (token == null) {
            sendErrorResponse(httpResponse, "非法登录", HttpStatus.UNAUTHORIZED.value());
            return;
        }

        String sessionId = JwtUtils.getSessionIdFromToken(token);
        String cacheKey = "sys:login:" + sessionId;
        if (sessionId == null || !redisUtils.hasKey(cacheKey)) {
            sendErrorResponse(httpResponse, "会话已失效，请重新登录", HttpStatus.UNAUTHORIZED.value());
            return;
        }
        if (!redisUtils.get(cacheKey).equals(token)) {
            sendErrorResponse(httpResponse, "用户信息丢失，请重新登录", HttpStatus.UNAUTHORIZED.value());
            return;
        }

        UserInfo userInfo = JwtUtils.getUserInfoFromToken(token);
        if (userInfo.getUserId() == null) {
            throw new ServletException("用户信息丢失，请重新登录");
        }

        try {
            UserContext.setCurrentUser(userInfo);
            chain.doFilter(request, response);
        } finally {
            UserContext.clear();
        }
    }

    private void sendErrorResponse(HttpServletResponse response, String message, int status) throws IOException {
        response.setStatus(status);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding("UTF-8");

        Response<Void> errorResponse = Response.error(HttpStatus.UNAUTHORIZED.value(), message);
        String json = new ObjectMapper().writeValueAsString(errorResponse);
        response.getWriter().write(json);
    }
}
